/* 
 * Header file for Vector3D
 * Programming by SochiX (http://sochix.ru)
 */

#ifndef _VECTOR3D_HPP
#define _VECTOR3D_HPP

#include <math.h>
#include <iostream>

class Vector3D
{
private:

public:
    double x,y,z;

    Vector3D() {};
    Vector3D(double px, double py, double pz) {x=px; y=py;z=pz;}
    Vector3D(const Vector3D& v) {x=v.x; y=v.y; z=v.z;}
    Vector3D operator= (const Vector3D& v) {x=v.x; y=v.y; z=v.z; return *this;}
    Vector3D operator+ ()const {return *this;}
    Vector3D operator- ()const {return Vector3D(-x,-y,-z);}
    Vector3D& operator+= (const Vector3D& v) {x+=v.x; y+=v.y; z+=v.z; return *this;}
    Vector3D& operator-= (const Vector3D& v) {x-=v.x; y-=v.y; z-=v.z; return *this;}
    Vector3D& operator*= (const Vector3D& v) {x*=v.x; y*=v.y; z*=v.z; return *this;}
    Vector3D& operator*= (float f) {x*=f; y*=f; z*=f; return *this;}
    Vector3D& operator/= (const Vector3D& v) {x/=v.x; y/=v.y; z/=v.z; return *this;}
    Vector3D& operator/= (float f) {x/=f; y/=f; z/=f; return *this;}
    double& operator[] (int index) {return *(index + &x);}
    int operator==(const Vector3D& v)const {return x==v.x && y==v.y && z==v.z;}
    int operator!=(const Vector3D& v)const {return x!=v.x || y!=v.y || z!=v.z;}

	double length() const {return (float)sqrt(x*x+y*y+z*z);}
	void print() const {std::cout << "x = " << x << "y = " << y << "z = " << z;}
	
   	friend Vector3D normalize(const Vector3D&);
    friend Vector3D operator+(const Vector3D&, const Vector3D&);
    friend Vector3D operator-(const Vector3D&, const Vector3D&);
    friend Vector3D operator*(const Vector3D&, const Vector3D&);
    friend Vector3D operator*(double, const Vector3D&);
    friend Vector3D operator*(const Vector3D&, double);
    friend Vector3D operator/(const Vector3D&, const Vector3D&);
    friend Vector3D operator/(const Vector3D&, double);
    friend double operator&(const Vector3D&, const Vector3D&);
};

inline Vector3D normalize(const Vector3D& v) {return Vector3D(v.x*((double)1/v.length()),v.y*((double)1/v.length()), v.z*((double)1/v.length()));}
inline Vector3D operator+(const Vector3D& u, const Vector3D& v) {return Vector3D(u.x+v.x,u.y+v.y,u.z+v.z);}
inline Vector3D operator-(const Vector3D& u, const Vector3D& v) {return Vector3D(u.x-v.x,u.y-v.y,u.z-v.z);}
inline Vector3D operator*(const Vector3D& u, const Vector3D& v) {return Vector3D(u.x*v.x,u.y*v.y,u.z*v.z);}
inline Vector3D operator*(double a, const Vector3D& v) {return Vector3D(v.x*a,v.y*a,v.z*a);}
inline Vector3D operator*(const Vector3D& v, double a) {return Vector3D(v.x*a,v.y*a,v.z*a);}
inline Vector3D operator/(const Vector3D& u, const Vector3D& v) {return Vector3D(u.x/v.x,u.y/v.y,u.z/v.z);}
inline Vector3D operator/(const Vector3D& v, double a) {return Vector3D(v.x/a,v.y/a,v.z/a);}
inline double operator& (const Vector3D& u, const Vector3D& v) {return u.x*v.x+u.y*v.y+u.z*v.z;} 


#endif	/* _VECTOR3D_HPP */

